﻿using System;
using System.Collections.Generic;

using Unity;
using Unity.Interception.InterceptionBehaviors;
using Unity.Interception.PolicyInjection.Pipeline;
using Microsoft.Practices.Unity.Configuration;

namespace pri.smilly.Demo {

    class Program {
        static void Main(string[] args) {
            IUnityContainer container = new UnityContainer();
            container.LoadConfiguration();

            IStudent student = container.Resolve<IStudent>();
            student.Print();
            student.Show();
        }
    }

    public class LogBehavior : IInterceptionBehavior {
        public bool WillExecute { get => true; }

        public IEnumerable<Type> GetRequiredInterfaces() => new[] { typeof(IStudent) };

        public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext) {
            if (input == null) throw new ArgumentNullException("input");
            if (getNext == null) throw new ArgumentNullException("getNext");

            Console.WriteLine("Before Execution");
            IMethodReturn result = getNext()(input, getNext);
            if (null != result.Exception)
                Console.WriteLine($"Exception Execution : {result.Exception.Message}");
            else
                Console.WriteLine("After Execution");

            Console.WriteLine("Final Execution");

            return result;
        }
    }

    public interface IStudent {
        void Show();

        void Print();
    }

    public class Student : IStudent {
        public void Show() {
            Console.WriteLine("method show executing ...");
            throw new Exception("method show execute error");
        }

        public void Print() {
            Console.WriteLine("method print executing ...");
        }
    }
}
